package com.usian.tu.service.ipl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usian.common.config.NewsAutoScanConstants;
import com.usian.model.atri.pojos.ApArticle;
import com.usian.model.atri.pojos.ApArticleConfig;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.common.config.WemediaContans;
import com.usian.tu.mapper.AdWmNewsMapper;
import com.usian.tu.mapper.AdwemediMapper;
import com.usian.tu.mapper.FabuMapper;
import com.usian.tu.mapper.WmNewsMaterialMapper;
import com.usian.tu.service.FabuService;
import com.usian.utils.threadlocal.WmThreadLocalUtils;
import org.apache.commons.net.nntp.Article;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class FabuServiceipl extends ServiceImpl<FabuMapper, WmNews> implements FabuService {


    @Resource
    private AdwemediMapper adwemediMapper;


    @Resource
    private AdWmNewsMapper adWmNewsMapper;

    @Resource
    KafkaTemplate kafkatemplat;
    @Resource
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    //文章发布
    @Override
    public ResponseResult list(WmNewsDto dto, Integer status) {
//        非空判断
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "不能为空");
        }
//       通过线程池 获取用户id 在wm_user 表中 对应登录用户的主键id
        Integer apUserId = WmThreadLocalUtils.getUser().getApUserId();
        if (apUserId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "不能为空");
        }
//      保存新闻  dto:前台传过来的发布内容
//      将状态 status  提交为1  草稿为0     apUserId：在wm_user 表中 对应登录用户的id
        WmNews wmNews = saveWmNews(dto, apUserId, status);
//        最后返回的是添加完成 或者修改完成Wmnews单表的一个操作

//        获取图片中的/url  将前台数据传入进去操作
        List<String> imageurl = getimageurl(dto);
//        操作完成后返回一个存储图片的集合

//        保存内容图片和素材之间的关系
//      传入imageurl  图片存储的list集合  wmNews对象    主题或者内容引用
//         saveContentImageMeteria(imageurl,wmNews,WemediaContans.WM_CONTENT_REFERENCE);

            saveWmNewsAndMaterial(imageurl, wmNews, 0);
//      最终操作 把WmNewsAndMaterial 中间表(wm_news_material) 进行数据的添加


//      参数:图片存储的list集合  wmNews对象   前台传过来的数据
            savainfoimage(imageurl, wmNews, dto);
            // 封面判断 是 几张图     Wmnews表的数据更新修改  中间表的更新操作



//发送kafka消息  将操作主表id发送   用来审核  判断
        kafkatemplat.send(NewsAutoScanConstants.WM_NEWS_AUTO_SCAN_TOPIC, JSON.toJSONString(wmNews.getId()));
        System.out.println("--------------卡夫卡发送成功----------------");
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public WmNews getbynew(Integer id) {
        WmNews byId = getById(id);
        return byId;
    }

//    定时器自动审核时候  走的全查
     @Override
    public List<Integer> zidongshenhe() {
        List<WmNews> list=list(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getStatus,8).lt(WmNews::getPublishTime,new Date()));
        List<Integer> list1=list.stream().map(WmNews::getId).collect(Collectors.toList());
        return list1;
    }
//上架或者下架
    @Override
    public ResponseResult shangxiajia(WmNews wmNews) {
        if (wmNews==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews1 = adWmNewsMapper.selectById(wmNews.getId());
        if (wmNews1.getEnable()==1){
            if (wmNews1.getStatus()==2){
               return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"审核失败的无法上架");

            }else {
                LambdaUpdateWrapper<WmNews> qw=new LambdaUpdateWrapper<>();
                qw.set(WmNews::getEnable,0);
                qw.eq(WmNews::getId,wmNews1.getId());
                adWmNewsMapper.update(wmNews1,qw);
//                ApArticleConfig apArticleConfig=new ApArticleConfig();
//                apArticleConfig.setArticleId(wmNews1.getArticleId());
//                apArticleConfig.setIsDown(0);
                Map<String ,String > map=new HashMap<>();
                map.put("ArticleId",wmNews1.getArticleId().toString());
                map.put("Enable","0");
                kafkatemplat.send(NewsAutoScanConstants.WM_NEWS_AUTO_ap_article_config,JSON.toJSONString(map));


              return   ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
            }
        }else if (wmNews1.getEnable()==0){
            LambdaUpdateWrapper<WmNews> qw=new LambdaUpdateWrapper<>();
            qw.set(WmNews::getEnable,1);
            qw.eq(WmNews::getId,wmNews1.getId());
            adWmNewsMapper.update(wmNews1,qw);
//                ApArticleConfig apArticleConfig=new ApArticleConfig();
//                apArticleConfig.setArticleId(wmNews1.getArticleId());
//                apArticleConfig.setIsDown(0);
            Map<String ,String > map=new HashMap<>();
            map.put("ArticleId",wmNews1.getArticleId().toString());
            map.put("Enable","1");
            kafkatemplat.send(NewsAutoScanConstants.WM_NEWS_AUTO_ap_article_config,JSON.toJSONString(map));


            return   ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

        }


        return    ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult findbyid(Integer id) {

        WmNews byId = getById(id);

        ResponseResult result = ResponseResult.okResult(byId);
        return result;
    }

    //进行媒体表进行修改 对里面的Reason列 和状态
    @Override
    public ResponseResult updateStatusAndReason(WmNews wmNews) {
        LambdaUpdateWrapper<WmNews> qw = new LambdaUpdateWrapper<>();
        qw.set(WmNews::getStatus, wmNews.getStatus());
        qw.set(WmNews::getReason, wmNews.getReason());
        qw.eq(WmNews::getId, wmNews.getId());
//        修改条件 通用方法对媒体表进行单表的修改
        adWmNewsMapper.update(wmNews,qw);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    // 封面判断 是 几张图     Wmnews表的数据更新修改  中间表的更新操作
    public ResponseResult savainfoimage(List<String> imageurl, WmNews wmNews, WmNewsDto dto) {
//        对前台传过来的dto中的状态进行判断  封面单图-1
        if (dto.getStatus() == WemediaContans.WM_NEWS_SINGLE_IMAGE) {
//            定义一个int 类型等于封面图片集合的长度
            int picnum = imageurl.size();
//            长度判断
            if (picnum > 2) {
//             wmNews对象中type   * 文章布局
//            0 无图文章
//            1 单图文章
//            3 多图文章 进行赋值
                wmNews.setType(WemediaContans.WM_NEWS_CONENT_MANY_IMAGE);
                imageurl = imageurl.stream().limit(3).collect(Collectors.toList());

            } else if (picnum <= 2 && picnum >= 0) {
                wmNews.setType(WemediaContans.WM_NEWS_CONENT_SINGLE_IMAGE);
                imageurl = imageurl.stream().limit(1).collect(Collectors.toList());

            } else {
                wmNews.setType(WemediaContans.WM_NEWS_CONENT_NONE_IMAGE);
            }


        }
//        WmNews表中的type文章布局修改
        LambdaUpdateWrapper<WmNews> qw = new LambdaUpdateWrapper<>();
//        修改参数赋值  布局   图片  主键id
//        qw.set(WmNews::getType, wmNews.getType());
////        toString传入的值带[] 要进行分割
        qw.set(WmNews::getImages, imageurl.toString().replace("[", "").replace("]", "").replace(" ", "").trim());
        qw.eq(WmNews::getId, wmNews.getId());
//        Wmnews表的数据更新修改
        adWmNewsMapper.update(wmNews, qw);
//findbyurl: 将图片集合 设置查询条件 去数据库中查询  将查询结果转成map 进行遍历操作 赋值给list.ingeter并返回
        List<Integer> ids = findbyurl(imageurl, wmNews);
//        再次进行中间表的更新操作   图片集合  主键id   1 主图引用  操作完成
        wmNewsMaterialMapper.insetContentMeteria(ids, wmNews.getId(), WemediaContans.WM_COVER_REFERENCE);
        return null;
    }

    //    获取url对应的地址  图片存储的list集合  wmNews对象
//    操作流程： 设置查询条件 去数据库中查询  将查询结果转成map 进行遍历操作 赋值给list.ingeter并返回
    public List<Integer> findbyurl(List<String> imageurl, WmNews wmNews) {
//       根据图片url去查询图片的id
        LambdaQueryWrapper<WmMaterial> qw = new LambdaQueryWrapper<>();
//        查询条件
        qw.in(WmMaterial::getUrl, imageurl);
        qw.eq(WmMaterial::getUserId, wmNews.getUserId());
//        素材中的uid 赋值为 wmNews对象中的uid

//        获取对应的图片数据  进行一个全查  条件就是wmNews对象中的uid和图片存储的list集合
        List<WmMaterial> wmMaterials = adwemediMapper.selectList(qw);
//      键值对  id,url
//     stream(): Java 8 新提供给开发者的一组操作集合的 API  Stream不调用终止方法，中间的操作不会执行。
//        collect() 方法，可以收集流中的数据到【集合】或者【数组】中去。 WmMaterial中数据个别参数 转换成键值对  url  - id
        Map<String, Integer> collect = wmMaterials.stream().collect(Collectors.toMap(WmMaterial::getUrl, WmMaterial::getId));
//遍历url
//        创建一个list.interger
        List<Integer> ids = new ArrayList<>();
//        将咱们图片存储的list.string进行遍历
        for (String url : imageurl) {
//获取遍历中每一个url 赋值给id
            Integer id = collect.get(url);
//            if (id==null){
//                return  ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"无效图片");
//            }
//            保存图片id
//            添加到list.integer集合
            ids.add(id);

        }
//        返回list.integer集合
        return ids;
    }

    //    保存新闻 wmnews 表数据的添加
    public WmNews saveWmNews(WmNewsDto dto, Integer apUserId, Integer status) {
//        执行添加媒体信息  前台dto数据赋值给WmNews实体类
        WmNews wmNews = addwmNews(dto);
//        赋值后的WmNews对象中主键id进行判断
//        这里进行添加或者修改的一个判断 判断是否有主键id
        if (wmNews.getId() == null) {
//            wmNews对象中的uid 赋值为wm_user中的主键id  news中的状态赋值  看是提交还是草草稿
            wmNews.setUserId(apUserId);
            wmNews.setStatus(status);
//将前台的dto中图片进行转换为字符串类型
            String images = dto.getImages().toString();
            if (images != null && images.length() > 0) {
//                判断转换后的图片是否为空 看前台是否传递图片  将其进行分割 应该转换成tostring后 两边是带[]号的
                String newimages = images.replace("[", "").replace("]", "");
//                分割完成将图片赋值到wmNews对象中images图片列中
                wmNews.setImages(newimages);
            }
//            将前台传过来的基本数据 添加到数据库中  wmNews 表的添加
            save(wmNews);
        } else {
//            如果主键id为空 代表要修改
//      wm_material  素材图片
            LambdaUpdateWrapper<WmNewsMaterial> qw = new LambdaUpdateWrapper<>();
//           修改条件  等于 素材中uid  赋值为 wmNews中的主键id
            qw.eq(WmNewsMaterial::getNewsId, wmNews.getId());
//            让他将  要修改的  新闻对应的素材删除
            wmNewsMaterialMapper.delete(qw);
//            修改新闻发布表中的基本信息
            adWmNewsMapper.updateById(wmNews);
        }

//返回wmNews对象
        return wmNews;
    }


    //    获取内容中的图片url 将前台的文本和图片进行分解
    public List<String> getimageurl(WmNewsDto dto) {
        //        获取内容的图片url
//        content是WmNews表中文本和图片存储列  这里将前台的本文图片消息进行赋值给string进行操作
        String content = dto.getContent();
//        创建一个list<String> imageurl
        List<String> imageurl = new ArrayList<>();
//        将json类型的进行一个转换  转换为list.mapper  map是容易操作  键值对 操作
        List<Map> maps = JSON.parseArray(content, Map.class);
//        将map遍历 遍历成map <key-value>都是字符串类型  都是为了容易操作
        for (Map<String, String> map : maps) {
//            在map循环中  获取类型为 image进行判断
//            if (mapper.get("type").equals(WemediaContans.WM_NEWS_TYPE_IMAGE)){
            if (map.get("type").equals("image")) {
//                再定义一个image字符串接收里面的map中image参数
                String image = map.get("value");
//                对获取的map中image参数的字符串进行判空  != 代表这个获取到参数了
                if (image != null) {
//                    将获取到的参数add添加到list.string中
                    imageurl.add(image);
                }
            }
        }
//      操作完成  将imageurl返回  list.string类型的一个返回值
        return imageurl;

    }


    //    保存内容图片和素材之间的关系
//      传入imageurl  图片存储的list集合  wmNews对象   主题或者内容引用
    public ResponseResult saveWmNewsAndMaterial(List<String> imageurl, WmNews wmNews, Integer type) {
//这里是将 图片存储的list集合  wmNews对象  传入进行操作
//        调用的别的方法  findbyurl

            List<Integer> ids = findbyurl(imageurl, wmNews);
//      findbyurl: 将图片集合 设置查询条件 去数据库中查询  将查询结果转成map 进行遍历操作 赋值给list.ingeter并返回


            //      获取新闻id  wmNews表中的主键id
            Integer wmid = wmNews.getId();
//        保存执行
//        参数:图片路径的list.integer 和 wmNews表中的主键id 和 主题或者内容引用
//        操作:wm_news_material中间表  进行添加的一个操作
            wmNewsMaterialMapper.insetContentMeteria(ids, wmid, 0);
//操作完成

        return null;
    }

    public WmNews addwmNews(WmNewsDto dto) {
        WmNews wmNews = new WmNews();
        wmNews.setChannelId(dto.getChannelId());
        wmNews.setId(dto.getId());
        wmNews.setContent(dto.getContent());
        wmNews.setCreatedTime(new Date());
        wmNews.setLabels(dto.getLabels());
        wmNews.setTitle(dto.getTitle());
        wmNews.setType(dto.getStatus());
        wmNews.setPublishTime(dto.getPublishTime());
        wmNews.setSubmitedTime(new Date());
        return wmNews;
    }
}
